<template>
  <el-card class="form-container" shadow="never">
    <div v-for="(api,index) in allApiList" :key="index" :class="index===0?'top-line':null">
      <el-row class="table-layout" style="background: #F2F6FC;">
        <el-checkbox
          :value="isAllChecked(api)"
          :indeterminate="isIndeterminate(api)"
          @change="handleCheckAllChange"
        >
          {{ api.categoryName }}
        </el-checkbox>
      </el-row>
      <el-row class="table-layout">
        <el-col v-for="(apiPermssion,apiIndex) in api.apiPermissionList" :key="apiIndex" :span="8" style="padding: 4px 0">
          <el-checkbox :value="selectApis[apiPermssion.id] && selectApis[apiPermssion.id].checked" @change="handleCheckChange(apiPermssion)">
            {{ apiPermssion.name }}
          </el-checkbox>
        </el-col>
      </el-row>
    </div>
    <div style="margin-top: 20px" align="center">
      <el-button type="primary" @click="handleSave()">保存</el-button>
      <el-button @click="handleClear()">清空</el-button>
    </div>

  </el-card>
</template>

<script>
import {
  getAlloc,
  getListByMenu,
  getListByComponent

} from '@/api/system/api-permission'

import { updateApiPermissions as updateMenuApiPermissions } from '@/api/system/menu'
import { updateApiPermissions as updateComponentApiPermissions } from '@/api/system/component'

export default {
  name: 'AllocResource',
  data() {
    return {
      uiType: null,
      menuId: null,
      componentId: null,

      allApiList: [],

      // 选择的api
      selectApis: {},

      // 每个分类下，选择的api数量
      cateSelectApiCounts: { }

    }
  },
  created() {
    this.getDataByParams()
  },
  methods: {
    getDataByParams() {
      const uiType = this.$route.query.uiType
      const id = this.$route.query.id

      // 如果没有提供ui类型，直接返回到菜单页

      if (uiType === undefined || id === undefined) {
        this.$router.push({
          path: '/system/permission/menu'
        })

        return
      }

      // 菜单
      if (uiType.toString() === '0') {
        this.menuId = id
        this.getListByMenu()
      } else if (uiType.toString() === '1') {
      // 组件
        this.componentId = id
        this.getListByComponent()
      } else {
        this.$router.push({
          path: '/system/permission/menu'
        })
      }

      this.getAlloc()
      this.uiType = uiType.toString()
    },
    getListByMenu() {
      getListByMenu(this.menuId).then(res => {
        const data = res.data
        this.calculateSelectApi(data)
      })
    },
    getListByComponent() {
      getListByComponent(this.componentId).then(res => {
        const data = res.data
        this.calculateSelectApi(data)
      })
    },

    calculateSelectApi(apis) {
      const selectApis = {}
      apis.map(item => {
        selectApis[item.id] = {}
        selectApis[item.id].checked = true
        selectApis[item.id].id = item.id
        selectApis[item.id].categoryId = item.categoryId
      })
      this.selectApis = selectApis

      this.calculateSelectApiCount()
    },
    calculateSelectApiCount() {
      this.cateSelectApiCounts = {}
      const selectApis = this.selectApis
      Object.keys(selectApis).map(key => {
        const value = selectApis[key]

        if (value && value.checked) {
          let cateSelectApiCount = this.cateSelectApiCounts[value.categoryId]
          if (!cateSelectApiCount) {
            cateSelectApiCount = {
              count: 0
            }
          }

          cateSelectApiCount.count++

          this.cateSelectApiCounts[value.categoryId] = cateSelectApiCount
        }
      })
    },
    getAlloc() {
      getAlloc().then(res => {
        this.allApiList = res.data
      })
    },
    isIndeterminate(api) {
      const cateSelectApiCounts = this.cateSelectApiCounts

      // 当前分类包含的api权限
      const apiPermissionList = api.apiPermissionList

      // 当前分类已经被选择的数量
      const apiCateCount = cateSelectApiCounts[api.categoryId]

      return apiCateCount && apiCateCount < apiPermissionList.length
    },
    isAllChecked(api) {
      const cateSelectApiCounts = this.cateSelectApiCounts
      return cateSelectApiCounts[api.categoryId] && cateSelectApiCounts[api.categoryId].count > 0
    },
    handleSave() {
      this.$confirm('是否保存关联的API？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        const apiPermissions = new Set()
        const uiType = this.uiType

        const selectApis = this.selectApis
        Object.keys(selectApis).map(key => {
          const value = selectApis[key]
          if (value.checked) {
            apiPermissions.add(value.id)
          }
        })

        if (uiType === '0') {
          updateMenuApiPermissions(this.menuId, Array.from(apiPermissions)).then(_ => {
            this.$message.success('保存API权限成功')
          })
        } else {
          updateComponentApiPermissions(this.componentId, Array.from(apiPermissions)).then(_ => {
            this.$message.success('保存API权限成功')
          })
        }
      })
    },
    handleClear() {
      this.selectApis = {}
      this.calculateSelectApiCount()
    },
    handleCheckAllChange(val) {
      if (val) {
        let apiPermissionList = []
        this.allApiList.map(api => {
          api.apiPermissionList.map(apiPermission => {
            apiPermissionList = apiPermissionList.concat(apiPermission)
          })
        })
        this.calculateSelectApi(apiPermissionList)
      } else {
        this.selectApis = {}
        this.calculateSelectApiCount()
      }
    },
    handleCheckChange(apiPermssion) {
      const selectApis = this.selectApis
      let currentApi = selectApis[apiPermssion.id]

      // 以前没有勾选api，进行初始化
      if (!currentApi) {
        currentApi = {
          categoryId: apiPermssion.categoryId,
          checked: false
        }
      }

      currentApi.checked = !currentApi.checked

      this.calculateSelectApiCount()
    }
  }
}
</script>

<style scoped>
  .table-layout {
    padding: 20px;
    border-left: 1px solid #DCDFE6;
    border-right: 1px solid #DCDFE6;
    border-bottom: 1px solid #DCDFE6;
  }

  .top-line {
    border-top: 1px solid #DCDFE6;
  }
</style>
